/*
 * Player.cpp
 *
 *  Created on: 21-08-2012
 *      Author: szymon
 */

#include "Player.h"
#include <cassert>
#include "SurfaceOps.h"

Player::Player(Screen * screen, vector<Flame *> * flames)
{
	//Initialize movement variables
	offSet = 0;
	velocity = 0;

	//Initialize animation variables
	frame = 0;
	direction = right;
	position = run;

	flameGeneration = false;
	//Load the sprite sheet
	playerSurface = SurfaceOps::loadImage("megaman.png");
	assert(playerSurface != NULL);

	camera.x = 0;
	camera.y = 0;
	camera.w = SCREEN_WIDTH;
	camera.h = SCREEN_HEIGHT;

	setClips();

	this->screen = screen;
	this->flames = flames;
}

Player::~Player()
{
	SDL_FreeSurface(playerSurface);
}

void Player::setClips()
{
	for (int i = 0; i < SPRITES_NUM; i++)
	{
		//Clip the sprites
		clipsRight[i].x = 0 + PLAYER_WIDTH * i;
		clipsRight[i].y = 0;
		clipsRight[i].w = PLAYER_WIDTH;
		clipsRight[i].h = PLAYER_HEIGHT;
	}

	for (int i = 0; i < SPRITES_NUM; i++)
	{
		//Clip the sprites
		clipsLeft[SPRITES_NUM - 1 - i].x = 0 + PLAYER_WIDTH * i;
		clipsLeft[SPRITES_NUM - 1 - i].y = PLAYER_HEIGHT;
		clipsLeft[SPRITES_NUM - 1 - i].w = PLAYER_WIDTH;
		clipsLeft[SPRITES_NUM - 1 - i].h = PLAYER_HEIGHT;
	}

	clipCrouchRight.x = 0;
	clipCrouchRight.y = PLAYER_HEIGHT * 2;
	clipCrouchRight.w = PLAYER_WIDTH;
	clipCrouchRight.h = PLAYER_HEIGHT;

	clipCrouchLeft.x = PLAYER_WIDTH;
	clipCrouchLeft.y = PLAYER_HEIGHT * 2;
	clipCrouchLeft.w = PLAYER_WIDTH;
	clipCrouchLeft.h = PLAYER_HEIGHT;
}

void Player::handleEvents(SDL_Event * event)
{
	//If a key was pressed
	if (event->type == SDL_KEYDOWN)
	{
		//Set the velocity
		switch (event->key.keysym.sym)
		{
		case SDLK_RIGHT:
			velocity += PLAYER_WIDTH / 8;
			break;
		case SDLK_LEFT:
			velocity -= PLAYER_WIDTH / 8;
			break;
		case SDLK_DOWN:
			position = crouch;
			break;
		case SDLK_SPACE:
			flameGeneration = true;
			break;
		default:
			break;
		}
	}
	//If a key was released
	else if (event->type == SDL_KEYUP)
	{
		//Set the velocity
		switch (event->key.keysym.sym)
		{
		case SDLK_RIGHT:
			velocity -= PLAYER_WIDTH / 8;
			break;
		case SDLK_LEFT:
			velocity += PLAYER_WIDTH / 8;
			break;
		case SDLK_DOWN:
			position = run;
			break;
		default:
			break;
		}
	}

	if (velocity < 0)
	{
		//Set the animation to left
		direction = left;
	}
	//If Player is moving right
	else if (velocity > 0)
	{
		//Set the animation to right
		direction = right;
	}
}

void Player::move()
{
	if(position == run)
	{
		//Move
		offSet += velocity;

		//Keep the stick figure in bounds
		if ((offSet < 0) || (offSet + PLAYER_WIDTH > LEVEL_WIDTH))
		{
			offSet -= velocity;
		}
	}
	if(flameGeneration)
	{
		flameGeneration = false;
		if(direction == right)
		{
			flames->push_back(new Flame(screen, offSet - camera.x, SCREEN_HEIGHT - PLAYER_HEIGHT - PLAYER_Y_OFFSET, Flame::right));
		}
		else
		{
			flames->push_back(new Flame(screen, offSet - camera.x -PLAYER_WIDTH, SCREEN_HEIGHT - PLAYER_HEIGHT - PLAYER_Y_OFFSET, Flame::left));
		}
	}
}

SDL_Rect Player::setCamera()
{
    //Center the camera over the dot
    camera.x = ( offSet + PLAYER_WIDTH/2  ) - SCREEN_WIDTH/2;

    //Keep the camera in bounds.
    if( camera.x < 0 )
    {
        camera.x = 0;
    }
    if( camera.x > LEVEL_WIDTH - camera.w )
    {
        camera.x = LEVEL_WIDTH - camera.w;
    }
    return camera;
}

void Player::showStand(void)
{
	//player is standing
	if (velocity == 0)
	{
		frame = 0;
	}
	//player is moving
	else
	{
		//Move to the next frame in the animation
		frame++;
	}

	//Loop the animation
	if (frame >= SPRITES_NUM)
	{
		frame = 2;
	}

	if (direction == right)
	{
		SurfaceOps::applySurface(offSet - camera.x,
				SCREEN_HEIGHT - PLAYER_HEIGHT - PLAYER_Y_OFFSET, playerSurface,
				screen->surface(), &clipsRight[frame]);
	}
	else if (direction == left)
	{
		SurfaceOps::applySurface(offSet - camera.x,
				SCREEN_HEIGHT - PLAYER_HEIGHT - PLAYER_Y_OFFSET, playerSurface,
				screen->surface(), &clipsLeft[frame]);
	}
}

void Player::showCrouch(void)
{
	frame = 1;
	if (direction == right)
	{
		SurfaceOps::applySurface(offSet - camera.x, SCREEN_HEIGHT - PLAYER_HEIGHT - PLAYER_Y_OFFSET, playerSurface, screen->surface(), &clipCrouchRight);
	}
	else if (direction == left)
	{
		SurfaceOps::applySurface(offSet - camera.x, SCREEN_HEIGHT - PLAYER_HEIGHT - PLAYER_Y_OFFSET, playerSurface, screen->surface(), &clipCrouchLeft);
	}
}

void Player::show()
{
	if(position == run)
	{
		showStand();
	}
	else if(position == crouch)
	{
		showCrouch();
	}
}


